<?php

namespace dingtalk;

use dingtalk\util\Http;
use think\Cache;
use think\helper\Str;

class Auth
{
    /**
     * 缓存accessToken。accessToken有效期为两小时，需要在失效前请求新的accessToken。
     * @return mixed
     */
    public static function getAccessToken()
    {
        if($_SERVER['HTTP_HOST']==config('dingtalk.DOMAIN')){
            $accessToken = Cache::get('corp_access_token');
            if(!$accessToken){
                $response = Http::get('/gettoken', array('corpid' => config('dingtalk.CORPID'), 'corpsecret' => config('dingtalk.SECRET')));
                $accessToken = $response->access_token;
                Cache::set('corp_access_token', $accessToken,7000);
            }
            return $accessToken;
        }else{
            $url = 'http://'.config('dingtalk.DOMAIN').'/home/public/getToken.html';
            $accessToken = Http::pget($url);
            return $accessToken;
        }
    }

    /**
     * 缓存jsTicket。jsTicket有效期为两小时，需要在失效前请求新的jsTicket（注意：以下代码没有在失效前刷新缓存的jsTicket）。
     */
    public static function getTicket($accessToken)
    {
        if($_SERVER['HTTP_HOST']==config('dingtalk.DOMAIN')){
            $jsticket = Cache::get('corp_js_ticket');
            if (!$jsticket)
            {
                $response = Http::get('/get_jsapi_ticket', array('type' => 'jsapi', 'access_token' => $accessToken));
                self::check($response);
                $jsticket = $response->ticket;
                Cache::set('corp_js_ticket', $jsticket,7000);
            }
            return $jsticket;
        }else{
            $url = 'http://'.config('dingtalk.DOMAIN').'/home/public/getjsticket.html';
            $jsticket = Http::pget($url);
            return $jsticket;
        }
    }

    /**
     * 通过CODE换取身份userid
     * @param $accessToken
     * @param $code
     * @return string
     */
    public static function getUserId($accessToken, $code)
    {
        $response = Http::get("/user/getuserinfo", ["access_token" => $accessToken, "code" => $code]);
        return obj2array($response);
    }
    /***************************************管理后台使用begin***************************************************/
    /**
     * 获取企业后台
     * @param $corpid
     * @param $ssosecret
     * @return mixed
     */
    public static function getSsoToken()
    {
        $ssoToken = Cache::get('corp_sso_token');
        if(!$ssoToken){
            $response = Http::get('/sso/gettoken', array('corpid' => config('dingtalk.CORPID'), 'corpsecret' => config('dingtalk.SSOSECRET')));
            $ssoToken = $response['access_token'];
            Cache::set('corp_sso_token', $ssoToken,7000);
        }
        return $ssoToken;
    }

    /**
     * 获取后台免登跳转链接
     * @param $redirectUrl
     * @return string
     */
    public static function getSsoRedirect($redirectUrl){
        $corpid = config('dingtalk.CORPID');
        $url = 'https://oa.dingtalk.com/omp/api/micro_app/admin/landing?corpid='.$corpid.'&redirect_url='.urlencode($redirectUrl);
        return $url;
    }
    /**
     * 通过CODE换取管理员用户身份信息
     * @param $accessToken
     * @param $code
     * @return string
     */
    public static function getUserinfo($ssoToken, $code)
    {
        $response = Http::get("/sso/getuserinfo", ["access_token" => $ssoToken, "code" => $code]);
        return obj2array($response);
    }
    /***************************************管理后台使用end***************************************************/

    /**
     * 当前url
     * @return string
     */
    function curPageURL()
    {
        $pageURL = 'http';
        if (array_key_exists('HTTPS',$_SERVER)&&$_SERVER["HTTPS"] == "on")
        {
            $pageURL .= "s";
        }
        $pageURL .= "://";
        if ($_SERVER["SERVER_PORT"] != "80")
        {
            $pageURL .= $_SERVER["HTTP_HOST"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
        }
        else
        {
            $pageURL .= $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
        }
        return $pageURL;
    }

    /**
     * 获取配置信息
     * @return string
     */
    public static function getConfig()
    {
        $corpId = config('dingtalk.CORPID');
        $agentId = config('dingtalk.AGENTID');
        $nonceStr = Str::random(8);
        $timeStamp = time();
        $url = self::curPageURL();
        $corpAccessToken = self::getAccessToken();
        if (!$corpAccessToken)
        {
            trace("[getConfig] ERR: no corp access token",'dingtalk');
        }
        $ticket = self::getTicket($corpAccessToken);
        $signature = self::sign($ticket, $nonceStr, $timeStamp, $url);
        $config = [
            'url' => $url,
            'nonceStr' => $nonceStr,
            'agentId' => $agentId,
            'timeStamp' => $timeStamp,
            'corpId' => $corpId,
            'signature' => $signature
        ];
        return json_encode($config, JSON_UNESCAPED_SLASHES);
    }

    /**
     * 设置签名
     * @param $ticket
     * @param $nonceStr
     * @param $timeStamp
     * @param $url
     * @return string
     */
    public static function sign($ticket, $nonceStr, $timeStamp, $url)
    {
        $plain = 'jsapi_ticket=' . $ticket .
            '&noncestr=' . $nonceStr .
            '&timestamp=' . $timeStamp .
            '&url=' . urldecode($url);
        return sha1($plain);
    }

    /**
     * 检测
     * @param $res
     */
    static function check($res)
    {
        if ($res->errcode != 0)
        {
            trace("FAIL: " . json_encode($res),'dingtalk');
            exit("Failed: " . json_encode($res));
        }
    }
}